package com.easyapi.web.controller.datasource;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.easyapi.common.contants.Constants;
import com.easyapi.common.enums.StatusCode;
import com.easyapi.common.exception.BizException;
import com.easyapi.common.param.datasource.AddDatasourceParam;
import com.easyapi.common.param.datasource.DataSourceOperationParam;
import com.easyapi.common.param.datasource.DataSourcePageParam;
import com.easyapi.common.utils.BaseResponse;
import com.easyapi.common.utils.ResultUtils;
import com.easyapi.common.vo.datasource.DataSourceListVo;
import com.easyapi.common.vo.datasource.DataSourcePageVo;
import com.easyapi.common.vo.metadata.TableStruct;
import com.easyapi.server.service.api.DataSourceService;
import io.swagger.annotations.Api;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * @author javadadi
 */
@RestController
@RequestMapping(Constants.BASE_URL + "datasource")
@Api(tags = {"EDatasource"})
public class DataSourceController {
    @Resource
    private DataSourceService dataSourceService;

    @PostMapping("/saveDatasource")
    public BaseResponse<Boolean> addDataSource(@RequestBody AddDatasourceParam param) {
        if (StringUtils.isAnyBlank(param.getDataName(), param.getDataDesc(), param.getDataJson())) {
            throw new BizException(StatusCode.PARAMS_ERROR);
        }
        if (StringUtils.isAnyBlank(param.getDatasourceUsername(), param.getDatasourcePassword())) {
            throw new BizException(StatusCode.PARAMS_ERROR);
        }
        if (Objects.isNull(param.getDataName()) && param.getId() <= 0) {
            throw new BizException(StatusCode.PARAMS_ERROR);
        }
        dataSourceService.saveDataSource(param);
        return ResultUtils.success(true);
    }

    @GetMapping("listDatasource")
    public BaseResponse<List<DataSourceListVo>> listDataSource() {
        List<DataSourceListVo> dataSourceListVos = dataSourceService.listDataSource();
        return ResultUtils.success(dataSourceListVos);
    }

    @PostMapping("/pageDatasource")
    public BaseResponse<Page<DataSourcePageVo>> pageDatasource(@RequestBody DataSourcePageParam param) {
        if (StringUtils.isNotEmpty(param.getDataName()) && param.getDataName().length() > 255) {
            throw new BizException(StatusCode.PARAMS_ERROR);
        }
        if (StringUtils.isNotEmpty(param.getDataDesc()) && param.getDataDesc().length() > 255) {
            throw new BizException(StatusCode.PARAMS_ERROR);
        }
        if (StringUtils.isNotEmpty(param.getDatasourceUsername()) && param.getDatasourceUsername().length() > 255) {
            throw new BizException(StatusCode.PARAMS_ERROR);
        }
        Page<DataSourcePageVo> page = dataSourceService.page(param);
        return ResultUtils.success(page);
    }

    @PostMapping("/testDatasourceConnect")
    public BaseResponse<Boolean> testDatasourceConnect(@RequestBody AddDatasourceParam param) {
        if (Objects.isNull(param.getId()) && StringUtils.isAnyBlank(param.getDataName(), param.getDataDesc(), param.getDataJson())) {
            throw new BizException(StatusCode.PARAMS_ERROR);
        }
         dataSourceService.testDataSourceConnection(param);
        return ResultUtils.success(true);
    }

    @PostMapping("/deleteDatasource")
    public BaseResponse<Boolean> deleteDatasource(@RequestBody DataSourceOperationParam param) {
        if (Objects.isNull(param.getId())) {
            throw new BizException(StatusCode.PARAMS_ERROR);
        }
        if (param.getId() <= 0) {
            throw new BizException(StatusCode.PARAMS_ERROR);
        }
         dataSourceService.removeDataSource(param.getId());
        return ResultUtils.success(true);
    }

    @PostMapping("/datasourceOperation")
    public BaseResponse<Boolean> datasourceOperation(@RequestBody DataSourceOperationParam param) {
        if (Objects.nonNull(param.getId()) && param.getId() <= 0) {
            throw new BizException(StatusCode.PARAMS_ERROR);
        }
        if(StringUtils.isEmpty(param.getAction())){
            throw new BizException(StatusCode.PARAMS_ERROR);
        }
        dataSourceService.datasourceOperation(param.getId(),param.getAction());
        return ResultUtils.success(true);
    }

    @PostMapping("/getAllDatabases")
    public BaseResponse<List<String>> getAllDatabases(@RequestBody DataSourceOperationParam param) {
        if (Objects.isNull(param.getId())) {
            throw new BizException(StatusCode.PARAMS_ERROR);
        }
        if (param.getId() <= 0) {
            throw new BizException(StatusCode.PARAMS_ERROR);
        }
        List<String> strings = dataSourceService.listAllDatabases(param.getId(), param.getDatabaseName());
        return ResultUtils.success(strings);
    }

    @PostMapping("/getAllTables")
    public BaseResponse<List<String>> getAllTables(@RequestBody DataSourceOperationParam param) {
        if (Objects.isNull(param.getId())) {
            throw new BizException(StatusCode.PARAMS_ERROR);
        }
        if (param.getId() <= 0) {
            throw new BizException(StatusCode.PARAMS_ERROR);
        }
        List<String> strings = dataSourceService.listAllTables(param.getId(), param.getDatabaseName(), param.getTableName());
        return ResultUtils.success(strings);
    }

    @PostMapping("getTableStruct")
    public BaseResponse<List<TableStruct>> getTableStruct(@RequestBody DataSourceOperationParam param) {
        if (Objects.isNull(param.getId())) {
            throw new BizException(StatusCode.PARAMS_ERROR);
        }
        if (param.getId() <= 0) {
            throw new BizException(StatusCode.PARAMS_ERROR);
        }
        if (StringUtils.isAnyBlank(param.getDatabaseName(), param.getTableName())) {
            throw new BizException(StatusCode.PARAMS_ERROR);
        }
        return dataSourceService.getTableStruct(param.getId(), param.getDatabaseName(), param.getTableName());
    }

    @PostMapping("getCreateTableSql")
    public BaseResponse<String> getCreateTableSql(@RequestBody DataSourceOperationParam param) {
        if (Objects.isNull(param.getId())) {
            throw new BizException(StatusCode.PARAMS_ERROR);
        }
        if (param.getId() <= 0) {
            throw new BizException(StatusCode.PARAMS_ERROR);
        }
        if (StringUtils.isAnyBlank(param.getDatabaseName(), param.getTableName())) {
            throw new BizException(StatusCode.PARAMS_ERROR);
        }
        String createSql = dataSourceService.getCreateSql(param.getId(), param.getDatabaseName(), param.getTableName());
        return ResultUtils.success(createSql);
    }

    @PostMapping("/getTableData")
    public BaseResponse<List<List<String>>> getTableData(@RequestBody DataSourceOperationParam param) {
        if (Objects.isNull(param.getId())) {
            throw new BizException(StatusCode.PARAMS_ERROR);
        }
        if (param.getId() <= 0) {
            throw new BizException(StatusCode.PARAMS_ERROR);
        }
        if (StringUtils.isAnyBlank(param.getDatabaseName(), param.getTableName())) {
            throw new BizException(StatusCode.PARAMS_ERROR);
        }
        List<List<String>> tableData = dataSourceService.getTableData(param.getId(), param.getDatabaseName(), param.getTableName());
        return ResultUtils.success(tableData);
    }

    @PostMapping("listDatasourceByProjectId")
    public BaseResponse<List<DataSourceListVo>> listDatasourceByProjectId(@RequestBody DataSourceOperationParam param) {
        if (Objects.isNull(param.getProjectId()) || param.getProjectId() <= 0) {
            throw new BizException(StatusCode.PARAMS_ERROR);
        }
        List<DataSourceListVo> dataSourceListVos = dataSourceService.listDatasourceByProjectId(param.getProjectId());
        return ResultUtils.success(dataSourceListVos);
    }
}
